import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;

/**
 *  计算器-版本二
 */
public class Calculator extends JFrame {
    private JTextField tf;
    private JPanel panel1, panel2, panel3, panel4;
    private String back;
    private boolean IfResult = true, flag = false;
    private String oper = "=";
    private double result = 0;
    private Num numActionListener;
    private DecimalFormat df;

    public Calculator() {
        super("多功能计算器");//设置标题栏
        df = new DecimalFormat("#.####");//保留四位小数
        this.setLayout(new BorderLayout(10, 5));
        panel1 = new JPanel(new GridLayout(1, 3, 10, 10));
        panel2 = new JPanel(new GridLayout(5, 6, 5, 5));//5行6列
        panel3 = new JPanel(new GridLayout(5, 1, 5, 5));
        panel4 = new JPanel(new BorderLayout(5, 5));
        numActionListener = new Num();//实现数字监听
        tf = new JTextField();
        tf.setEditable(false);//文本区域不可编辑
        tf.setBackground(Color.white);//文本区域的背景色
        tf.setHorizontalAlignment(JTextField.RIGHT);//文字右对齐
        tf.setText("0");
        tf.setBorder(BorderFactory.createLoweredBevelBorder());
        init();//对计算器进行初始化
    }

    private void init() {
        addButton(panel1, "Backspace", new Clear(), Color.black);
        addButton(panel1, "CE", new Clear(), Color.black);
        addButton(panel1, "C", new Clear(), Color.black);
        addButton(panel2, "1/x", new Signs(), Color.magenta);
        addButton(panel2, "log", new Signs(), Color.magenta);
        addButton(panel2, "7", numActionListener, Color.blue);
        addButton(panel2, "8", numActionListener, Color.blue);
        addButton(panel2, "9", numActionListener, Color.blue);
        addButton(panel2, "÷", new Signs(), Color.red);
        addButton(panel2, "n!", new Signs(), Color.magenta);
        addButton(panel2, "sqrt", new Signs(), Color.magenta);
        addButton(panel2, "4", numActionListener, Color.blue);
        addButton(panel2, "5", numActionListener, Color.blue);
        addButton(panel2, "6", numActionListener, Color.blue);
        addButton(panel2, "×", new Signs(), Color.red);
        addButton(panel2, "sin", new Signs(), Color.magenta);
        addButton(panel2, "x^2", new Signs(), Color.magenta);
        addButton(panel2, "1", numActionListener, Color.blue);
        addButton(panel2, "2", numActionListener, Color.blue);
        addButton(panel2, "3", numActionListener, Color.blue);
        addButton(panel2, "-", new Signs(), Color.red);
        addButton(panel2, "cos", new Signs(), Color.magenta);
        addButton(panel2, "x^3", new Signs(), Color.magenta);
        addButton(panel2, "0", numActionListener, Color.blue);
        addButton(panel2, "-/+", new Clear(), Color.blue);
        addButton(panel2, ".", new Dot(), Color.blue);
        addButton(panel2, "+", new Signs(), Color.red);
        addButton(panel2, "tan", new Signs(), Color.magenta);
        addButton(panel2, "%", new Signs(), Color.magenta);
        addButton(panel2, "π", numActionListener, Color.orange);
        addButton(panel2, "e", numActionListener, Color.orange);
        addButton(panel2, "′″", new Signs(), Color.orange);
        addButton(panel2, "=", new Signs(), Color.red);
        JButton btns = new JButton("计算器");
        btns.setBorder(BorderFactory.createLoweredBevelBorder());
        btns.setEnabled(false);//按钮不可操作
        btns.setPreferredSize(new Dimension(20, 20));
        panel3.add(btns);//加入按钮
        addButton(panel3, "MC", null, Color.black);
        addButton(panel3, "MR", null, Color.black);
        addButton(panel3, "MS", null, Color.black);
        addButton(panel3, "M+", null, Color.black);
        panel4.add(panel1, BorderLayout.NORTH);
        panel4.add(panel2, BorderLayout.CENTER);
        this.add(tf, BorderLayout.NORTH);
        this.add(panel3, BorderLayout.WEST);
        this.add(panel4);
        pack();
        this.setResizable(false);//窗口不可改变大小
        this.setLocation(300, 200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void addButton(JPanel panel, String name, ActionListener action, Color color) {
        JButton bt = new JButton(name);
        panel.add(bt);//在面板上增加按钮
        bt.setForeground(color);//设置前景（字体）颜色
        bt.addActionListener(action);//增加监听事件
    }

    private void getResult(double x) {
        if ("+".equals(oper)) {
            result += x;
        } else if ("-".equals(oper)) {
            result -= x;
        } else if ("×".equals(oper)) {
            result *= x;
        } else if ("÷".equals(oper)) {
            result /= x;
        } else if ("=".equals(oper)) {
            result = x;
        }
        tf.setText(df.format(result));
    }

    class Signs implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String str = e.getActionCommand();
            /* sqrt求平方根 */
            if ("sqrt".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                if (i >= 0) {
                    tf.setText(String.valueOf(df.format(Math.sqrt(i))));
                } else {
                    tf.setText("负数不能开平方根");
                }
            }
            /* log求常用对数 */
            else if ("log".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                if (i > 0) {
                    tf.setText(String.valueOf(df.format(Math.log(i))));
                } else {
                    tf.setText("负数不能求对数");
                }
            }
            /* %求百分比 */
            else if ("%".equals(str)) {
                tf.setText(df.format(Double.parseDouble(tf.getText()) / 100));
            }
            /* 1/x求倒数 */
            else if ("1/x".equals(str)) {
                if (Double.parseDouble(tf.getText()) == 0) {
                    tf.setText("除数不能为零");
                } else {
                    tf.setText(df.format(1 / Double.parseDouble(tf.getText())));
                }
            }
            /* sin求正弦函数 */
            else if ("sin".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                tf.setText(String.valueOf(df.format(Math.sin(i))));
            }
            /* cos求余弦函数 */
            else if ("cos".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                tf.setText(String.valueOf(df.format(Math.cos(i))));
            }
            /* tan求正切函数 */
            else if ("tan".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                tf.setText(String.valueOf(df.format(Math.tan(i))));
            }
            /* n!求阶乘 */
            else if ("n!".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                //判断为整数放进行阶乘操作
                if ((i % 2 == 0) || (i % 2 == 1))
                {
                    int j = (int) i;//强制类型转换
                    int result = 1;
                    for (int k = 1; k <= j; k++) {
                        result *= k;
                    }
                    tf.setText(String.valueOf(result));
                } else {
                    tf.setText("无法进行阶乘");
                }
            }
            /* x^2求平方 */
            else if ("x^2".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                tf.setText(String.valueOf(df.format(i * i)));
            }
            /* x^3求立方 */
            else if ("x^3".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                tf.setText(String.valueOf(df.format(i * i * i)));
            } else if ("′″".equals(str)) {
                double i = Double.parseDouble(tf.getText());
                tf.setText(String.valueOf(i / 180 * Math.PI));
            } else {
                if (flag) {
                    IfResult = false;
                }
                if (IfResult) {
                    oper = str;
                } else {
                    getResult(Double.parseDouble(tf.getText()));
                    oper = str;
                    IfResult = true;
                }
            }
        }
    }

    class Clear implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String str = e.getActionCommand();
            if ("C".equals(str)) {
                tf.setText("0");
                IfResult = true;
                result = 0;
            } else if ("-/+".equals(str)) {
                double i = 0 - Double.parseDouble(tf.getText().trim());
                tf.setText(df.format(i));
            } else if ("Backspace".equals(str)) {
                if (Double.parseDouble(tf.getText()) > 0) {
                    if (tf.getText().length() > 1) {
                        tf.setText(tf.getText().substring(0, tf.getText().length() - 1));
                        //使用退格删除最后一位字符
                    } else {
                        tf.setText("0");
                        IfResult = true;
                    }
                } else {
                    if (tf.getText().length() > 2) {
                        tf.setText(tf.getText().substring(0, tf.getText().length() - 1));
                    } else {
                        tf.setText("0");
                        IfResult = true;
                    }
                }
            } else if ("CE".equals(str)) {
                tf.setText("0");
                IfResult = true;
            }
        }
    }

    class Num implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String str = e.getActionCommand();
            if (IfResult) {
                tf.setText("");
                IfResult = false;
            }
            if ("π".equals(str)) {
                tf.setText(String.valueOf(Math.PI));
            } else if ("e".equals(str)) {
                tf.setText(String.valueOf(Math.E));
            } else {
                tf.setText(tf.getText().trim() + str);
                if ("0".equals(tf.getText())) {
                    tf.setText("0");
                    IfResult = true;
                    flag = true;
                }
            }
        }
    }

    class Dot implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            IfResult = false;
            if (!tf.getText().trim().contains(".")) {
                tf.setText(tf.getText() + ".");
            }
        }
    }

    public static void main(String[] args) {
        new Calculator().setVisible(true);
    }
}
